#!/usr/bin/perl -w 

### Notes:
# The -T for security check would help to protect the script but was giving error and was removed.
# The arguments been used as parameterson external commands/scripts. For the arguments only hexadecimal and - are allowed. Feel free ADD extra protectiong.

# TODO: Handle undefined $1
# TODO: Lock files

use POSIX qw(strftime);
use URI::Escape;
use Fcntl qw(:DEFAULT :flock);

use FCTranscode;

### Start og main program ###


# TODO Usage
# Process command line argument arguments 
#if ($#ARGV!=1) {
#	print "Usage: $0 batchid jobid";
#	exit 0;
#}

$remote_id = $ARGV[0];

$remote_id = uri_unescape($remote_id);;

open(FH, "<", $collector_file); # TODO - Handle erros and empty.
flock FH, LOCK_SH;
# There shouldnt be a request if it's empty or non-existent 
@list = <FH>;
flock FH, LOCK_UN;
close FH;

#print "Remoteid: $remote_id\n";
$sel_item = "";
foreach $item (@list){
	print "Item: $item\n";
	$sel_item = $item;
	if ($item =~ /remote_id=\'$remote_id\'/){
		print "MATCH for $remote_id\n";
		$item_remote_id = $remote_id;
		$item =~ /col_status=\'(\w+)\'/;
		print "col_status: $1\n";
		if ($1 eq 'finished') {print 'It\'s already finished\n'; exit}
		elsif ($1 ne 'waiting') {print 'Unknown col_status value'; exit}

		print "Waiting....\n";

		$item =~ /transcoder=\'(\w+)\'/;
		$transcoder = $1;
		print "Transcoder: $1\n";
		# Need to make two line bellow obsolete
		if ($transcoder eq 'compressor') {
			$transcoder = 'COMPRESSOR';
			$item =~ /jobid=\'([[:xdigit:]-]{36})\'/;
			$jobid = $1;
                        print "Jobid: $1\n";

			$item =~ /batchid=\'([[:xdigit:]-]{36})\'/;
			$batchid = $1;
			print "Batchid: $1\n";
		}
		elsif ($transcoder eq 'ffmpeg') {
			$transcoder = 'FFMPEG';
			$item =~ /jobid=\'(\/[\w\/\.]+\.\d+\.status)\'/;
			$jobid = $1;
                        print "Jobid: $1\n";

		}
		else {print "Unknown transcoder $transcoder\n";}
		last;
	}
}
if ($item_remote_id ne $remote_id) {print "No remote_id $item_remote_id in collector status";}
#print "The SEL: $sel_item\n";

# Filtering arguments (if changing the pattern please do the same on the calling program(ServiceInterface.java))
#$transcoder = $ARGV[0]; This could be removed
if ($transcoder eq 'COMPRESSOR') {


	#print "jobid: $jobid\n";
	#print "batchid: $batchid\n";
	if (!( $batchid =~ /\A[[:xdigit:]-]{36}\z/ )) { error_die("ERROR:2002: Invalid batchid."); exit 1; }
	if (!( $jobid =~ /\A[[:xdigit:]-]{36}\z/ )) { error_die("ERROR:2003: Invalid jobid."); exit 1; }

	# Kill using Batch Monitor
	$cmd_str = "/Applications/Utilities/Batch\\ Monitor.app/Contents/MacOS/Batch\\ Monitor -clustername \"This Computer\" -kill -jobid \"$jobid\" -batchid \"$batchid\"";

	#print $cmd_str."\n";
	$output = qx/$cmd_str/;
	#print "BM KILL output: $output\n";

	# Confirm cancellation

	sleep2;
	# Using monitor.pl instead of Monitor Batch?
	#$cmd_str = "/Applications/Utilities/Batch\\ Monitor.app/Contents/MacOS/Batch\\ Monitor -clustername \"This Computer\""; 
	# TODO - check if monitor.pl exists
	$cmd_str = $monitor_loc." \"$jobid\"";

	$output = qx/$cmd_str/;	#TODO - Check for timeouts

	open($rh, "<", \$output);	# Handle errors

	# Is it working with the false and true keywords? I dont thing so
	$confirmed = false;
	while($line = readline $rh){
        	if ($line =~ /\A<jobStatus/){
                	$line =~ /jobid=\"([[:xdigit:]-]{36})/;
                	if ($1 eq $jobid) {
                        	$line =~ /status=\"([\w\:\ ]+)\"/;
                        	if ($1 eq 'Cancelled') {$confirmed = true; last;}
                	}
        	}
	}
	close $rh;
	if ($confirmed) {
		remove_item($sel_item);
		print "OK\n"; }
	else { error_die("ERROR:3016: Transcoding cancelation failed."); }
}
elsif ($transcoder eq 'FFMPEG') {
	if (!( $jobid =~ /\A.*\..*\.\d+\.status\z/ )) { error_die("ERROR:2004: Invalid ffmpeg status file: $jobid"); exit 1; }

	#print $jobid;
	$lsof_out = `lsof -F a $jobid`; # TODO - Check if lsof didn't return an error
	
	#print "LSOF_OUT: $lsof_out";

	open $rh, "<", \$lsof_out;  #handle errors
	while ($pid = readline $rh) {
		$mode = readline $rh;

		chomp($pid);
		chomp($mode);

		$pid =~ /\Ap(\d+)\z/;
		$pid = $1;

		$mode =~ /\Aa(\w+)\z/;
		$mode = $1;


		#print "$pid:$mode\n";
		if ($mode =~ /w/) {
			system("kill -KILL $pid"); # TODO - Check if returned no errors
			sleep 2;
			my $ps_out = `ps -p $pid`; # TODO - Check if returned no errors
			#print "PS_OUT: $ps_out";
			if ($ps_out =~ /ffmpeg/) { error_die("ERROR:3016: Transcoding cancelation failed."); }
			else {
				remove_item($sel_item);
				print 'OK';
			}
		}
	}
}
else { error_die("ERROR:2005: Invalid transcoder: $transcoder"); }

